/**
 * 
 */
package problem;

import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Set;

import core.Problem;
import core.Result;

/**
 * @author tptak
 *
 */
public abstract class PortfolioProblem extends Problem {


	protected double predictions[];
	protected double realValues[];

	protected double value[];
	protected String names[];
	
	@Override
	public String performAnalysis(Double capital, Integer analysisNumber, Set<Result> results) {
		//result[0] = predicted_return_rate;
		//result[1] = predicted_risk;
		String ret = new String();

		DecimalFormat df = new DecimalFormat("0.00");
		DecimalFormat dfDetailed = new DecimalFormat("0.00000000");

		Result [] resultSortedByRisk =  results.toArray(new Result[results.size()]);
		int [][] shares = new int [analysisNumber+1] [resultSortedByRisk[0].genotype.length];
		
		double capitalRest = capital;
		Arrays.sort(resultSortedByRisk, new Comparator<Result>(){
			//compare only predicted risk
			@Override
			public int compare(Result arg0, Result arg1) {
				double diff = arg1.result[0] - arg0.result[0];
				if (diff > 0)
					return -1;
				if (diff < 0)
					return 1;
				return 0;

			}}
		);

		int i = 0, j = 0, jj = 0;
		int incj = resultSortedByRisk.length/analysisNumber;
		double tmp = 0, tmpvalue = 0;

		ret += ("Analysis for the capital "+df.format(capital)+"\n");
		
		while (jj<analysisNumber){ //loop - all analysis
			double predictedValue = 0.0;
			double realReturn = 0.0;
			double risk = resultSortedByRisk[j].result[0] ;
			double returnRate = resultSortedByRisk[j].result[1] ;
			double [] genotype = resultSortedByRisk[j].genotype; 
			double genoSum = 0;
			capitalRest = capital;
			int num = 0;

			//przewidywana stopa zwrotu i ryzyka
			ret += ((jj+1) + ". Theoretical predicted risk: " + dfDetailed.format(risk) + 
					", return rate score: " + dfDetailed.format(returnRate)+
			"\n  No\tname\t\t  %\tto buy\tvalue of one");
			
			//sumujemy genotyp
			try {
				i = 0;
				while (true){
					genoSum += genotype[i];
					i++;
				}
			}catch (IndexOutOfBoundsException iex){
				//BLA!
			}
			try {
				i = 0;
				while (true){
					//wypisanie nazwy akcji, obliczenie ilosci (ca�kowitej) do zakupu
					//TODO obliczenie faktycznego zysku przy takim sk�adzie portfela
					tmp = (genotype[i] / genoSum) * capital;
					num = 0;
					tmpvalue = value[i];
					tmp -= tmpvalue;
					while (tmp > 0.0){
						num++;
						tmp -= tmpvalue;
					}
					shares[jj][i] = num;
					capitalRest -= (num * tmpvalue);

					predictedValue += (num * tmpvalue)*(1+this.predictions[i]);
					realReturn += num*realValues[i];
					ret += ("\n  "+ (i+1) +".\t" 
							+ String.format("%-"+12+"s", this.names[i]) +"\t" 
							+ String.format("%"+6+"s",df.format((genotype[i] / genoSum)*100))+ "\t"
							+ String.format("%"+6+"s",num)+"\t"
							+ String.format("%"+6+"s",df.format(tmpvalue))); 
					i++;
				}
			} catch (IndexOutOfBoundsException iex){
				
			}
			//incrementing j
			j += incj;
			jj++;
			double predictedReturn = predictedValue+capitalRest;
			realReturn += capitalRest;
			ret += ("\n  Capital used: "+df.format(capital-capitalRest)+
					"\n  Rest of the capital: "+df.format(capitalRest)+
					"\n  Predicted return: "+df.format(predictedReturn)+
					"\n  Predicted return rate: "+dfDetailed.format((predictedReturn -capital)*100.0/capital)+"%"+
					"\n  Real return: "+df.format(realReturn)+
					"\n  Real return rate: "+dfDetailed.format((realReturn -capital)*100.0/capital)+"%"+
					"\n\n");
			
		}

		return ret;
	}
}
